package com.community.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.community.entity.Infos;
import com.community.entity.MyJson;
import com.community.entity.School;
import com.community.entity.Student;
import com.community.service.*;
import com.community.util.*;
import com.community.util.wechat.WeChatAuth;
import com.community.util.wechat.WebAccessToken;
import com.community.util.wechat.WechatService;
import com.feng.fengDUtil.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.SortedMap;

/**
 * 无需登录就能访问的接口
 */
@RestController
@RequestMapping(value = "/wx")
public class WxAction {
    @Autowired
    private InfoService infoService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private WechatService wechatService;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private MajorService majorService;

    @Autowired
    private DictService dictService;
    /**
     * 微信认证用
     * @param wc
     * @return
     */
    @RequestMapping(value="/wxAuth",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public void wxAuth(WeChatAuth wc,HttpServletRequest request, HttpServletResponse response) throws IOException {

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        PrintWriter out = response.getWriter();
        try {
            if (isGet) {
                out.write(wechatService.wxAuth(wc));
            } else {
                String respMessage = wechatService.weixinPost(request);
                System.out.println("respMessage=["+respMessage+"]");
                if (respMessage!=null) {
                    out.write(respMessage);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            out.close();
        }

    }

    @RequestMapping(value="/createMenu",method = RequestMethod.GET)
    @ResponseBody
    public String createMenu(){
       return wechatService.createMenu();
    }

    /**
     * 微信认证
     * @param code
     * @return
     */
    @RequestMapping(value = "/wechatAuth", method = RequestMethod.GET)
    public ModelAndView wechatAuth(@RequestParam("code") String code, @RequestParam("state") String state, HttpSession session) {
        ModelAndView view = new ModelAndView();
        WebAccessToken webToken = wechatService.getWebToken(code);
        String openid = webToken.getOpenid();
        session.setAttribute("openid",openid);
        String access_token=webToken.getAccess_token();
        Student student = studentService.getByOpenid(openid);
        if(student!=null){
            SessionUtil.studentLogin(student);
        }
        switch (state){
            case "MainPage":view.setView(new RedirectView("/index.html#/MainPage", false));break;
            case "UserCenter":view.setView(new RedirectView("/index.html#/UserCenter", false));break;
            case "test":view.setView(new RedirectView("/index.html#/test/test", false));break;
            case "order":view.setView(new RedirectView("/index.html#/login/order", false));break;
        }
        return view;
    }

    //微信支付通知回调处理
    @ResponseBody
    @RequestMapping("wxPayNotify")
    public String vipPayNotifyProcess(HttpServletRequest request) {
        System.out.print("------支付回调-------");
        try {
            //获取微信通知信息并转换为Map
            SortedMap<String, String> resultMap = (SortedMap<String, String>) wechatService.XMLToMap(request.getInputStream());
            //生成签名信息
            String sign = wechatService.getSign(resultMap);
            //判断签名是否一致
            if (!sign.equals(resultMap.get("sign"))) {
                System.out.print("支付回调签名错误");
                return "FAIL";
            }
            System.out.print("支付回调签名通过");
            //业务处理
            //判断是否支付成功
            if("SUCCESS".equals(resultMap.get("return_code"))&&"SUCCESS".equals(resultMap.get("result_code"))){
                String orderId = resultMap.get("out_trade_no");//订单号
                String amount = resultMap.get("total_fee");//订单金额
                /*String orderId = "20180322113306644";//订单号
                String amount = "0.01";*/
                //修改预支付订单信息：根据订单ID，支付金额
               studentService.payComplete(orderId,resultMap.get("openid"));
                //VIP设置
            }
            return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
        } catch (Exception e) {
            e.printStackTrace();
            return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
        }
    }


    @PostMapping("login")
    public Result postLogin(
            @RequestParam(value = "username") String userName,
            @RequestParam(value = "password") String password,
            @RequestParam String verifyCode,HttpSession session){
        try {
            String realverifyCode =  (String)session.getAttribute("verifyCode");
            if(!verifyCode.equalsIgnoreCase(realverifyCode)){
                return Result.error("验证码错误！");
            }
            session.removeAttribute("verifyCode");
            Student student= studentService.findStudent(userName, password);
            String openid = (String) session.getAttribute("openid");
            System.out.println("当前是微信登录!openid:"+openid);
            if(StringUtils.isNotEmpty(openid)){
                student.setOpen_id( openid);
                studentService.update(student);
            }
            SessionUtil.studentLogin(student);
            JSONObject obj = new JSONObject();
            obj.put("userInfo",studentService.curStudent());
            obj.put("allDict",dictService.allDict());
            return Result.success(obj);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(e.getMessage());
        }
    }

    /**
     * 供app用户登录
     * @return
     */
    @RequestMapping(value = "/logout")
    public Result logout() {
        SessionUtil.studentLogout();
        return Result.success();
    }


    //短信验证码
    @ResponseBody
    @RequestMapping("sendSmsForReg")
    public Result sendSmsForReg(@RequestParam String phone,HttpSession session)  {
        Date sendSmsForRegTime = (Date)session.getAttribute("sendSmsForRegTime");
        if(sendSmsForRegTime!=null && sendSmsForRegTime.after(new Date())){
            return Result.error("1分钟内已发送过验证码，请稍候！");
        }
        Student student = studentService.findStudent(phone);
        if(student!=null){
            return Result.error("此手机号码已注册，请登录！");
        }

        sendSmsForRegTime = DateUtils.getTimeByMinute(1);
        session.setAttribute("sendSmsForRegTime",sendSmsForRegTime);
        String verifyCode = (Math.random()+"").substring(2,8);
        try {
            MessageUtil.message(phone, verifyCode);
            session.setAttribute("verifyCodeForReg",verifyCode+"#"+phone);
            return Result.success();
        } catch (ClientException e) {
            e.printStackTrace();
            return Result.error(e.getErrMsg());
        }
    }

    @ResponseBody
    @RequestMapping("sendSmsForModify")
    public Result sendSmsForModify(@RequestParam String phone,HttpSession session)  {
        Date sendSmsForModifyTime = (Date)session.getAttribute("sendSmsForModifyTime");
        if(sendSmsForModifyTime!=null && sendSmsForModifyTime.after(new Date())){
            return Result.error("1分钟内已发送过验证码，请稍候！");
        }
        Student student = studentService.findStudent(phone);
        if(student ==null){
            return Result.error("此手机号未注册！");
        }

        sendSmsForModifyTime = DateUtils.getTimeByMinute(1);
        session.setAttribute("sendSmsForModifyTime",sendSmsForModifyTime);
        String verifyCode = (Math.random()+"").substring(2,8);
        try {
            MessageUtil.message(phone, verifyCode);
            session.setAttribute("verifyCodeForModify",verifyCode+"#"+phone);
            return Result.success();
        } catch (ClientException e) {
            e.printStackTrace();
            return Result.error(e.getErrMsg());
        }
    }

    @ResponseBody
    @PostMapping("register")
    public Result register(@RequestParam String username,@RequestParam String password,@RequestParam String verifyCode,HttpSession session)  {

        String verifyCodeForReg = (String)session.getAttribute("verifyCodeForReg");
        if(verifyCodeForReg==null || !(verifyCode+"#"+username).equalsIgnoreCase(verifyCodeForReg)){
            return Result.error("验证码错误！");
        }
        Student student = new Student();
        String openid = (String) session.getAttribute("openid");
        if(openid!=null){
            Student existsOne = studentService.getByOpenid(openid);
            if(existsOne != null){
                student = existsOne;
            }
            student.setOpen_id(openid);
        }
        student.setUsername(username);
        student.setPassword(Md5Util.encodePassword(password,StudentService.SALT));
        student.setCreate_date(new Date());
        student.setPhone(username);
        studentService.saveOrUpdate(student);
        return Result.success(student);
    }

    @ResponseBody
    @PostMapping("modifyPassword")
    public Result modifyPassword(@RequestParam String username,@RequestParam String password,@RequestParam String verifyCode,HttpSession session)  {

        String verifyCodeForModify = (String)session.getAttribute("verifyCodeForModify");
        if(verifyCodeForModify==null || !(verifyCode+"#"+username).equalsIgnoreCase(verifyCodeForModify)){
            return Result.error("验证码错误！");
        }
        Student student = studentService.findStudent(username);
        student.setPassword(Md5Util.encodePassword(password,StudentService.SALT));
        studentService.update(student);
        return Result.success(student);
    }

    /**
     * 获取最新的三条新闻
     * @param page
     * @param search
     * @return
     */
    @RequestMapping(value = "/latestNews")
    public Result latestNews(Page page, Search search) {
        page.setPageSize(10);
        infoService.query(page,search);
        return Result.success(page);
    }

    @RequestMapping(value = "/news/{id}")
    public Result news(@PathVariable("id") String id) {
        return Result.success(infoService.selectById(Infos.class,id));
    }

    @RequestMapping(value = "/school/{id}")
    public Result school(@PathVariable("id") String id) {
        return Result.success(schoolService.selectById(School.class,id));
    }

    @RequestMapping(value = "/querySchool")
    public Result querySchool(Page page, Search search) {
        schoolService.query(page,search);
        return Result.success(page);
    }

    @RequestMapping(value = "/major/categories")
    public Result categories(String id) {
        return Result.success(majorService.listCategories(id));
    }

    @RequestMapping(value = "/major/specialties")
    public Result listSpecialties(String id) {
        return Result.success(majorService.listSpecialties(id));
    }
    @RequestMapping(value = "/major/specialtyDetail")
    public Result specialtyDetail(String id) {
        return Result.success(majorService.specialtyDetail(id));
    }

    @RequestMapping(value = "/existsSchool")
    public Result existsSchool(String name) {
        return Result.success(schoolService.existsSchool(name));
    }

    @RequestMapping(value = "/test")
    public Result test(@RequestBody MyJson myJson) {
        System.out.println(myJson.getJson());
        infoService.saveOrUpdate(myJson);
        return Result.success(myJson);
    }

    @GetMapping(value = "/downloadCollections")
    public void downloadCollections(String studentId,HttpServletResponse resp) throws IOException {
        Workbook wookbook = majorService.downloadCollections(studentId);
        resp.setContentType("application/octet-stream");
        //通知浏览器下载文件而不是打开
        String fileName =  java.net.URLEncoder.encode("模拟志愿.xls", "UTF-8");
        resp.addHeader("Content-Disposition", "attachment; filename="+fileName);
        ServletOutputStream out = resp.getOutputStream();
        wookbook.write(out);
    }

    @GetMapping(value = "/download/{studentId}.xlsx")
    public void download(@PathVariable String studentId,HttpServletResponse resp) throws IOException {
        Workbook wookbook = majorService.downloadCollections(studentId);
        resp.setContentType("application/octet-stream");
        //通知浏览器下载文件而不是打开
        String fileName =  java.net.URLEncoder.encode(studentId+".xlsx", "UTF-8");
        resp.addHeader("Content-Disposition", "attachment; filename="+fileName);
        ServletOutputStream out = resp.getOutputStream();
        wookbook.write(out);
    }

}
